package me.weijing.common.http;

import java.io.File;
import java.io.FileInputStream;
import java.net.HttpURLConnection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import me.weijing.common.AppManager;
import me.weijing.common.ApplicationHelper;
import me.weijing.common.R;
import me.weijing.common.util.NetworkUtils;

import org.json.JSONObject;

import android.app.Activity;
import android.content.Context;

/**
 * 异步请求数据
 * 
 * @author jiayuan.luo 2013-8-16下午2:53:08
 * @version 1.0.0
 * @category 杭州尤拉夫科技有限公司(微警)
 */
public abstract class WeiJingASyncJsonHttpRequestBase extends ActivityASyncJsonHttpRequestBase {

    public static Class<?> logoutedActivity;

    public static Class<?> getLogoutedActivity() {
        return logoutedActivity;
    }

    public static void setLogoutedActivity(Class<?> logoutedActivity) {
        WeiJingASyncJsonHttpRequestBase.logoutedActivity = logoutedActivity;
    }

    public WeiJingASyncJsonHttpRequestBase(Context context) {
        super(context);
        ApplicationHelper.initEnv(context);
        mCallback = new HttpProgressCallbackImpl2();
        if (null == gExtraHeader) {
            gExtraHeader = new ConcurrentHashMap<String, String>();
        }
        if (gExtraHeader.containsKey("deviceId") == false)
            gExtraHeader.put("deviceId", ApplicationHelper.getDeviceId());

        getSwitchUrl(context);
    }

    private void getSwitchUrl(Context context) {
    }

    @Override
    public Map<String, String> getExtraUrlParam() {
        Map<String, String> params = new ConcurrentHashMap<String, String>();
        return params;
    }

    @Override
    protected String buildUrl(RequestParams reqParam) throws Exception {

        String url = getUrl();
        if (url == null) {
            throw new Exception("not sepcified url");
        }
        url = url.trim();
        StringBuffer realUrl = new StringBuffer(url);
        if (-1 == url.indexOf('?')) {
            realUrl.append("?");
        } else {
            if (url.endsWith("&") == false)
                realUrl.append("&");
        }

        Map<String, String> extraUrlParam = getExtraUrlParam();
        if (null == extraUrlParam) {
            if (null != reqParam)
                realUrl.append(reqParam.toString());
            return realUrl.toString();
        }
        RequestParams extraUrlParam2 = new RequestParams(extraUrlParam);
        realUrl.append(extraUrlParam2.toString());
        if (null != reqParam) {
            realUrl.append("&");
            realUrl.append(reqParam.toString());
        }
        return realUrl.toString();
    }

    protected String buildPostUrl(RequestParams reqParam) throws Exception {

        String url = getUrl();
        if (url == null) {
            throw new Exception("not sepcified url");
        }
        url = url.trim();
        StringBuffer realUrl = new StringBuffer(url);
        if (-1 == url.indexOf('?')) {
            realUrl.append("?");
        } else {
            if (url.endsWith("&") == false)
                realUrl.append("&");
        }

        if (null != reqParam)
            realUrl.append(reqParam.toString());
        return realUrl.toString();

    }

    @Override
    public void aPost(RequestParams reqParam) {
        try {
            String realurl = buildPostUrl(null);
            mThreadPool.execute(new HttpRequestPost(realurl, realurl, mCallback, gExtraHeader, reqParam));
        } catch (Exception e) {
            e.printStackTrace();
            try {
                processFailed(EFailType.EFAILTYPE_SYS, FAILTYPE_CLIENT_CREATETHREAD, null, null);
                processFinish();
            } catch (Exception e2) {
                e2.printStackTrace();
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }

    public void aPut(RequestParams reqParam) {
        try {
            String realurl = buildPostUrl(null);
            String httpPut = "put";
            mThreadPool.execute(new HttpRequestPost(realurl, realurl, mCallback, gExtraHeader, reqParam, httpPut));
        } catch (Exception e) {
            e.printStackTrace();
            try {
                processFailed(EFailType.EFAILTYPE_SYS, FAILTYPE_CLIENT_CREATETHREAD, null, null);
                processFinish();
            } catch (Exception e2) {
                e2.printStackTrace();
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }

    @Override
    public void aPost(JSONObject jsonParam) {
        try {
            String realurl = this.buildUrl(null);
            mThreadPool.execute(new HttpRequestJsonPost(realurl, realurl, mCallback, gExtraHeader, jsonParam));
        } catch (Exception e) {
            e.printStackTrace();
            try {
                processFailed(EFailType.EFAILTYPE_SYS, FAILTYPE_CLIENT_CREATETHREAD, "创建线程失败", null);
                processFinish();
            } catch (Exception e2) {
                e2.printStackTrace();
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }

    @Override
    public void aPostFile(String filePath, String fileName, Map<String, String> extraParam) {

        try {
            String realurl = buildPostUrl(null);
            String key = "uploadfile";
            RequestParams reqParam = new RequestParams(extraParam);
            reqParam.put(key, new FileInputStream(new File(filePath)), fileName);
            mThreadPool.execute(new HttpRequestPost(realurl, realurl, mCallback, gExtraHeader, reqParam));
        } catch (Exception e) {
            e.printStackTrace();
            try {
                processFailed(EFailType.EFAILTYPE_SYS, FAILTYPE_CLIENT_CREATETHREAD, "创建线程失败", null);
                processFinish();
            } catch (Exception e2) {
                e2.printStackTrace();
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }

    @Override
    public void processFailed(EFailType failType, int resultCode, String errMsg, JSONObject data) {
        if (failType == EFailType.EFAILTYPE_APP && HttpURLConnection.HTTP_UNAUTHORIZED == resultCode) {
            if (Activity.class.isInstance(mContext) && !((Activity) mContext).isFinishing()) {
                ApplicationHelper.uninitEnv(mContext);
            }

        } else {
            if (Activity.class.isInstance(mContext) && !((Activity) mContext).isFinishing()) {
                if (!NetworkUtils.isNetworkAvailable(mContext)) {
                }
            }
        }
    }

    @Override
    public void processCanceled() {

    }

    @Override
    public void launchProgress() {

    }

    @Override
    public void processFinish() {
    }

    @Override
    public void publishProgress(int progress) {

    }

    class HttpProgressCallbackImpl2 implements HttpProgressCallback {
        private boolean bCanceled = false;

        public void setCanceled(boolean bCancel) {
            this.bCanceled = bCancel;
        }

        @Override
        public boolean isCanceled() {
            return bCanceled;
        }

        @Override
        public void startProgress() {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (checkSessionTag() == false)
                        return;
                    try {
                        launchProgress();

                    } catch (Exception e) {
                        e.printStackTrace();
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                }
            });
        }

        @Override
        public void progressPublish(final int progress) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (checkSessionTag() == false)
                        return;
                    try {
                        publishProgress(progress);

                    } catch (Exception e) {
                        e.printStackTrace();
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                }
            });
        }

        /**
         * 返回的请求数据
         * 
         * @param data
         *            为null表示请求失败
         */
        @Override
        public void interpret(byte[] data) {
            JSONObject jsonObj1 = null;
            int errCode = FAILTYPE_NETFAIL;
            String msg = mContext.getString(R.string.network_execute_error);
            if (null != data) {
                try {
                    jsonObj1 = new JSONObject(new String(data, "UTF-8"));
                } catch (Exception e) {
                    e.printStackTrace();
                    msg = mContext.getString(R.string.network_execute_error);
                    errCode = FAILTYPE_SERVER_FAIL;
                    data = null;
                }
            }
            try {
                if (null == data) {
                    final String errMsg = msg;
                    final int appErrCode = errCode;
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (checkSessionTag() == false)
                                return;
                            try {
                                processFailed(EFailType.EFAILTYPE_SYS, appErrCode, errMsg, null);

                            } catch (Exception e) {
                                e.printStackTrace();
                            } catch (Throwable t) {
                                t.printStackTrace();
                            }
                            try {
                                processFinish();
                            } catch (Exception e) {
                                e.printStackTrace();
                            } catch (Throwable t) {
                                t.printStackTrace();
                            }
                        }
                    });
                } else {

                    final JSONObject jsonObj = jsonObj1;
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (checkSessionTag() == false)
                                return;
                            try {
                                int httpCode = jsonObj.getJSONObject("meta").getInt("code");
                                if (HttpURLConnection.HTTP_OK == httpCode) {

                                    if (AppManager.isActivityDestroyed(mContext)) {
                                        // processFailed(EFailType.EFAILTYPE_APP,0,
                                        // "",jsonObj);
                                        // fix when net
                                    } else {
                                        processResult(jsonObj);
                                    }
                                } else {
                                    String errorMsg = null;
                                    errorMsg = jsonObj.getJSONObject("meta").getString("message");

                                    processFailed(EFailType.EFAILTYPE_APP, httpCode, errorMsg, jsonObj);
                                }

                            } catch (Exception e) {
                                e.printStackTrace();
                            } catch (Throwable t) {
                                t.printStackTrace();
                            }
                            try {
                                processFinish();
                            } catch (Exception e) {
                                e.printStackTrace();
                            } catch (Throwable t) {
                                t.printStackTrace();
                            }
                        }
                    });
                }
            } catch (Exception e) {

                e.printStackTrace();
            } catch (Throwable e) {

                e.printStackTrace();
            }
        }

        @Override
        public void serverFail(final int httpCode) {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    if (checkSessionTag() == false)
                        return;
                    try {
                        processFailed(EFailType.EFAILTYPE_APP, httpCode, "", null);

                    } catch (Exception e) {
                        e.printStackTrace();
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                    try {
                        processFinish();
                    } catch (Exception e) {
                        e.printStackTrace();
                    } catch (Throwable t) {
                        t.printStackTrace();
                    }
                }
            });

        }

        @Override
        public void interpret(byte[] data, Map<String, List<String>> responseHeaders) {
            interpret(data);
        }
    }
}
